package com.zenithmind.document.pojo.query;

import com.zenithmind.common.pojo.query.BaseQueryDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 文档评分查询DTO
 * 遵循单一职责原则：专注于评分查询条件
 * 遵循开闭原则：支持查询条件的扩展
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "文档评分查询DTO")
public class DocumentRatingQueryDTO extends BaseQueryDTO {

    @Schema(description = "文档ID", example = "doc123456")
    private String documentId;

    @Schema(description = "文档ID列表")
    private List<String> documentIds;

    @Schema(description = "用户ID", example = "user123456")
    private String userId;

    @Schema(description = "用户ID列表")
    private List<String> userIds;

    @Schema(description = "最小评分", example = "3.0")
    private Double minRating;

    @Schema(description = "最大评分", example = "5.0")
    private Double maxRating;

    @Schema(description = "评分范围", example = "[4.0, 5.0]")
    private List<Double> ratingRange;

    @Schema(description = "评论关键词", example = "很好")
    private String commentKeyword;

    @Schema(description = "评分标签", example = "有用")
    private String ratingTag;

    @Schema(description = "评分标签列表")
    private List<String> ratingTags;

    @Schema(description = "评分类型", example = "GENERAL", allowableValues = {"GENERAL", "EXPERT", "PEER_REVIEW", "AUTOMATED"})
    private String ratingType;

    @Schema(description = "评分类型列表")
    private List<String> ratingTypes;

    @Schema(description = "评分来源", example = "WEB", allowableValues = {"WEB", "MOBILE", "API", "SYSTEM"})
    private String ratingSource;

    @Schema(description = "评分来源列表")
    private List<String> ratingSources;

    @Schema(description = "是否匿名", example = "false")
    private Boolean isAnonymous;

    @Schema(description = "是否推荐", example = "true")
    private Boolean recommendToOthers;

    @Schema(description = "推荐理由关键词", example = "实用")
    private String recommendReasonKeyword;

    @Schema(description = "使用场景", example = "学习")
    private String usageScenario;

    @Schema(description = "使用场景列表")
    private List<String> usageScenarios;

    @Schema(description = "最小阅读时长（分钟）", example = "10")
    private Integer minReadingDuration;

    @Schema(description = "最大阅读时长（分钟）", example = "120")
    private Integer maxReadingDuration;

    @Schema(description = "文档版本", example = "v1.2")
    private String documentVersion;

    @Schema(description = "文档版本列表")
    private List<String> documentVersions;

    @Schema(description = "最小评分权重", example = "0.5")
    private Double minRatingWeight;

    @Schema(description = "最大评分权重", example = "2.0")
    private Double maxRatingWeight;

    @Schema(description = "最小置信度", example = "0.7")
    private Double minConfidence;

    @Schema(description = "最大置信度", example = "1.0")
    private Double maxConfidence;

    @Schema(description = "情感倾向", example = "POSITIVE", allowableValues = {"POSITIVE", "NEUTRAL", "NEGATIVE"})
    private String sentiment;

    @Schema(description = "情感倾向列表")
    private List<String> sentiments;

    @Schema(description = "关键词", example = "质量")
    private String keyword;

    @Schema(description = "关键词列表")
    private List<String> keywords;

    @Schema(description = "改进建议关键词", example = "增加")
    private String improvementSuggestionKeyword;

    @Schema(description = "相关文档", example = "doc789")
    private String relatedDocument;

    @Schema(description = "相关文档列表")
    private List<String> relatedDocuments;

    @Schema(description = "评分上下文关键词", example = "project")
    private String ratingContextKeyword;

    @Schema(description = "设备信息", example = "PC")
    private String deviceInfo;

    @Schema(description = "设备信息列表")
    private List<String> deviceInfos;

    @Schema(description = "IP地址", example = "192.168.1.100")
    private String ipAddress;

    @Schema(description = "IP地址列表")
    private List<String> ipAddresses;

    @Schema(description = "用户代理关键词", example = "Chrome")
    private String userAgentKeyword;

    @Schema(description = "扩展属性关键词", example = "category")
    private String extendedPropertiesKeyword;

    @Schema(description = "备注关键词", example = "搜索")
    private String remarksKeyword;

    @Schema(description = "更新原因关键词", example = "调整")
    private String updateReasonKeyword;

    @Schema(description = "审核状态", example = "APPROVED", allowableValues = {"PENDING", "APPROVED", "REJECTED"})
    private String reviewStatus;

    @Schema(description = "审核状态列表")
    private List<String> reviewStatuses;

    @Schema(description = "审核意见关键词", example = "合理")
    private String reviewCommentKeyword;

    @Schema(description = "是否置顶", example = "false")
    private Boolean isPinned;

    @Schema(description = "是否公开", example = "true")
    private Boolean isPublic;

    @Schema(description = "状态", example = "ACTIVE", allowableValues = {"ACTIVE", "INACTIVE", "HIDDEN", "DELETED"})
    private String status;

    @Schema(description = "状态列表")
    private List<String> statuses;

    @Schema(description = "是否有评论", example = "true")
    private Boolean hasComment;

    @Schema(description = "是否有标签", example = "true")
    private Boolean hasTags;

    @Schema(description = "是否有维度评分", example = "false")
    private Boolean hasDimensions;

    @Schema(description = "是否有改进建议", example = "true")
    private Boolean hasImprovementSuggestions;

    @Schema(description = "是否有相关文档", example = "false")
    private Boolean hasRelatedDocuments;

    @Schema(description = "最小点赞数", example = "5")
    private Integer minLikeCount;

    @Schema(description = "最大点赞数", example = "100")
    private Integer maxLikeCount;

    @Schema(description = "最小举报数", example = "0")
    private Integer minReportCount;

    @Schema(description = "最大举报数", example = "5")
    private Integer maxReportCount;

    @Schema(description = "创建时间开始", example = "2025-01-01T00:00:00")
    private LocalDateTime createTimeStart;

    @Schema(description = "创建时间结束", example = "2025-01-31T23:59:59")
    private LocalDateTime createTimeEnd;

    @Schema(description = "更新时间开始", example = "2025-01-01T00:00:00")
    private LocalDateTime updateTimeStart;

    @Schema(description = "更新时间结束", example = "2025-01-31T23:59:59")
    private LocalDateTime updateTimeEnd;

    @Schema(description = "排序字段", example = "createTime", allowableValues = {
            "createTime", "updateTime", "rating", "likeCount", "reportCount", "confidence"
    })
    private String sortField;

    @Schema(description = "排序方向", example = "DESC", allowableValues = {"ASC", "DESC"})
    private String sortDirection;

    @Schema(description = "分组字段", example = "ratingType", allowableValues = {
            "ratingType", "ratingSource", "sentiment", "usageScenario", "deviceInfo", "status"
    })
    private String groupBy;

    @Schema(description = "统计类型", example = "AVG", allowableValues = {"COUNT", "SUM", "AVG", "MAX", "MIN"})
    private String statisticsType;

    @Schema(description = "时间聚合粒度", example = "DAY", allowableValues = {"HOUR", "DAY", "WEEK", "MONTH"})
    private String timeGranularity;

    @Schema(description = "是否包含已删除", example = "false")
    private Boolean includeDeleted;

    @Schema(description = "是否只查询高分评价", example = "false")
    private Boolean onlyHighRatings;

    @Schema(description = "是否只查询低分评价", example = "false")
    private Boolean onlyLowRatings;

    @Schema(description = "是否只查询专家评分", example = "false")
    private Boolean onlyExpertRatings;

    @Schema(description = "是否只查询最新评分", example = "false")
    private Boolean onlyLatestRatings;

    /**
     * 验证查询条件
     */
    public boolean isValid() {
        // 评分范围验证
        if (minRating != null && maxRating != null) {
            if (minRating > maxRating || minRating < 1.0 || maxRating > 5.0) return false;
        }
        
        // 阅读时长范围验证
        if (minReadingDuration != null && maxReadingDuration != null) {
            if (minReadingDuration > maxReadingDuration || minReadingDuration < 0) return false;
        }
        
        // 权重范围验证
        if (minRatingWeight != null && maxRatingWeight != null) {
            if (minRatingWeight > maxRatingWeight || minRatingWeight < 0.1 || maxRatingWeight > 2.0) return false;
        }
        
        // 置信度范围验证
        if (minConfidence != null && maxConfidence != null) {
            if (minConfidence > maxConfidence || minConfidence < 0.0 || maxConfidence > 1.0) return false;
        }
        
        // 点赞数范围验证
        if (minLikeCount != null && maxLikeCount != null) {
            if (minLikeCount > maxLikeCount || minLikeCount < 0) return false;
        }
        
        // 举报数范围验证
        if (minReportCount != null && maxReportCount != null) {
            if (minReportCount > maxReportCount || minReportCount < 0) return false;
        }
        
        // 时间范围验证
        if (createTimeStart != null && createTimeEnd != null) {
            if (createTimeStart.isAfter(createTimeEnd)) return false;
        }
        
        if (updateTimeStart != null && updateTimeEnd != null) {
            if (updateTimeStart.isAfter(updateTimeEnd)) return false;
        }
        
        return true;
    }

    /**
     * 是否有评分范围查询
     */
    public boolean hasRatingRangeQuery() {
        return minRating != null || maxRating != null || (ratingRange != null && !ratingRange.isEmpty());
    }

    /**
     * 是否有时间范围查询
     */
    public boolean hasTimeRangeQuery() {
        return createTimeStart != null || createTimeEnd != null ||
               updateTimeStart != null || updateTimeEnd != null;
    }

    /**
     * 是否有关键词查询
     */
    public boolean hasKeywordQuery() {
        return commentKeyword != null || recommendReasonKeyword != null ||
               improvementSuggestionKeyword != null || ratingContextKeyword != null ||
               userAgentKeyword != null || extendedPropertiesKeyword != null ||
               remarksKeyword != null || updateReasonKeyword != null ||
               reviewCommentKeyword != null || keyword != null;
    }

    /**
     * 是否有质量指标查询
     */
    public boolean hasQualityQuery() {
        return minRatingWeight != null || maxRatingWeight != null ||
               minConfidence != null || maxConfidence != null ||
               minLikeCount != null || maxLikeCount != null ||
               minReportCount != null || maxReportCount != null;
    }

    /**
     * 是否有内容查询
     */
    public boolean hasContentQuery() {
        return hasComment != null || hasTags != null || hasDimensions != null ||
               hasImprovementSuggestions != null || hasRelatedDocuments != null;
    }

    /**
     * 是否有设备查询
     */
    public boolean hasDeviceQuery() {
        return deviceInfo != null || (deviceInfos != null && !deviceInfos.isEmpty()) ||
               ipAddress != null || (ipAddresses != null && !ipAddresses.isEmpty()) ||
               userAgentKeyword != null;
    }

    /**
     * 获取默认排序
     */
    public String getDefaultSort() {
        return "createTime DESC";
    }

    /**
     * 是否查询高分评价
     */
    public boolean isQueryHighRatings() {
        return onlyHighRatings != null && onlyHighRatings;
    }

    /**
     * 是否查询低分评价
     */
    public boolean isQueryLowRatings() {
        return onlyLowRatings != null && onlyLowRatings;
    }

    /**
     * 是否查询专家评分
     */
    public boolean isQueryExpertRatings() {
        return onlyExpertRatings != null && onlyExpertRatings;
    }

    /**
     * 是否查询最新评分
     */
    public boolean isQueryLatestRatings() {
        return onlyLatestRatings != null && onlyLatestRatings;
    }

    /**
     * 获取有效评分范围
     */
    public double[] getEffectiveRatingRange() {
        double min = minRating != null ? minRating : 1.0;
        double max = maxRating != null ? maxRating : 5.0;
        
        if (ratingRange != null && ratingRange.size() >= 2) {
            min = Math.max(min, ratingRange.get(0));
            max = Math.min(max, ratingRange.get(1));
        }
        
        return new double[]{min, max};
    }

    /**
     * 是否为复杂查询
     */
    public boolean isComplexQuery() {
        return hasRatingRangeQuery() || hasKeywordQuery() || hasQualityQuery() || 
               hasContentQuery() || hasDeviceQuery() || hasTimeRangeQuery();
    }
}
